package com.lagou.server;

import com.lagou.Mapper;
import com.lagou.bean.HttpRequest;
import com.lagou.bean.HttpResponse;
import com.lagou.utils.HttpProtocolUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.InputStream;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;

/**
 * 处理request线程
 */
public class RequestProcessor implements Runnable {
    private final Socket socket;
    private final Mapper mapper;

    public RequestProcessor(Socket socket, Mapper mapper) {
        this.socket = socket;
        this.mapper = mapper;
    }

    @Override
    public void run() {
        try {
            HttpRequest request = this.httpRequest();
            HttpResponse resp = new HttpResponse(socket.getOutputStream());
            String url = StringUtils.defaultIfEmpty(request.getUrl(), "/");
            Optional<Mapper.Host> first = mapper.getHosts().stream().findFirst();

            if (first.isPresent()) {
                List<Mapper.Context> contexts = first.get().getContexts();

                for (Mapper.Context c : contexts) {
                    String appBase = c.getAppBase();

                    for (Mapper.Wrapper w : c.getWrappers()) {
                        String contextPath = "/" + c.getName();
                        String contextUrl = contextPath + w.getUrlPattern();
                        if (url.startsWith(contextPath)) {
                            /**
                             * 如果是servlet, 执行servlet的service方法,
                             * 如果不是,则输出静态文件
                             */
                            if (url.equals(contextUrl)) {
                                w.getServlet().service(request, resp);
                            } else {
                                Path staticPath = Paths.get(appBase, url);
                                File staticFile = staticPath.toFile();
                                // 存在静态文件,则输出静态文件,不存在,则输出404
                                if (staticFile.exists() && staticFile.isFile()) {
                                    String content = Files.readString(staticPath);
                                    resp.outputContent(content);
                                } else {
                                    resp.getOutputStream().write(HttpProtocolUtil.getHttpHeader404().getBytes());
                                }
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(socket);
        }
    }

    /**
     * 构造httpRequest对象
     * @return
     * @throws Exception
     */
    public HttpRequest httpRequest() throws Exception {
        InputStream inputStream = this.socket.getInputStream();
        int count = 0;
        while (count == 0) {
            count = inputStream.available();
        }
        byte[] bytes = new byte[count];
        inputStream.read(bytes);
        String inputStr = new String(bytes);
        String firstLineStr = inputStr.split("\\n")[0]; // GET / HTTP/1.1
        String[] strings = firstLineStr.split(" ");
        String method = strings[0];
        String url = strings[1];
        System.out.println("=====>>method:" + method);
        System.out.println("=====>>url:" + url);

        return new HttpRequest(inputStream).setUrl(url).setMethod(method);
    }
}
